/**
 * Copyright 2015 bingoogolapple
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.bingoogolapple.badgeview;

import ohos.agp.components.Component;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

/**
 * BGABadgeViewUtil
 *
 * @since 2021-04-21
 */
public class BGABadgeViewUtil {
    private BGABadgeViewUtil() {
    }

    /**
     * dp px
     *
     * @param context Context
     * @param dpValue float
     * @return int
     */
    public static int dp2px(Context context, float dpValue) {
        return (int) AttrUtil.dip2px(context, dpValue);
    }

    /**
     * sp Two px
     *
     * @param context Context
     * @param spValue float
     * @return int
     */
    public static int sp2px(Context context, float spValue) {
        return (int) AttrUtil.sp2px(context, spValue);
    }

    /**
     * createBitmapSafely
     *
     * @param dragBadgeView Component
     * @param rect          Rect
     * @param retryCount    int
     * @return PixelMap
     */
    public static PixelMap createBitmapSafely(Component dragBadgeView, Rect rect, int retryCount) {
        try {
            PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
            options.pixelFormat = PixelFormat.ARGB_8888;
            return getBitmapFromView(dragBadgeView);
        } catch (OutOfMemoryError e) {
            e.getMessage();
            if (retryCount > 0) {
                System.gc();
                return createBitmapSafely(dragBadgeView, rect, retryCount - 1);
            }
            return null;
        }
    }

    /**
     * Component 转换成 PixelMap
     *
     * @param view Component
     * @return PixelMap
     */
    public static PixelMap getBitmapFromView(Component view) {
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.size = new Size(view.getWidth(), view.getHeight());
        options.pixelFormat = PixelFormat.ARGB_8888;
        options.editable = true;
        return PixelMap.create(options);
    }

    /**
     * getDistanceBetween2Points
     *
     * @param p0 Point
     * @param p1 Point
     * @return float
     */
    public static float getDistanceBetween2Points(Point p0, Point p1) {
        float distance = (float) Math.sqrt(Math.pow(NumberUtil.sub(p0.getPointY() , p1.getPointY()) , 2)
                + Math.pow(NumberUtil.sub(p0.getPointX() , p1.getPointX()) , 2));
        return distance;
    }

    /**
     * getMiddlePoint
     *
     * @param p1 Point
     * @param p2 Point
     * @return Point
     */
    public static Point getMiddlePoint(Point p1, Point p2) {
        double xAdd = NumberUtil.add(p1.getPointX() , p2.getPointX());
        double yAdd = NumberUtil.add(p1.getPointY() , p2.getPointY());
        return new Point((float) NumberUtil.div(xAdd , 2.0f) , (float) NumberUtil.div(yAdd , 2.0f));
    }

    /**
     * getPointByPercent
     *
     * @param p1      Point
     * @param p2      Point
     * @param percent float
     * @return Point
     */
    public static Point getPointByPercent(Point p1, Point p2, float percent) {
        return new Point(evaluate(percent, p1.getPointX(), p2.getPointX()), evaluate(percent, p1.getPointY(), p2.getPointY()));
    }

    /**
     * 从FloatEvaluator中拷贝过来,这样就不用每次都new FloatEvaluator了
     *
     * @param fraction   fraction
     * @param startValue Number
     * @param endValue   Number
     * @return Float
     */
    public static Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }

    /**
     * getIntersectionPoints
     *
     * @param pMiddle Point
     * @param radius  float
     * @param lineK   Double
     * @return Point[]
     */
    public static Point[] getIntersectionPoints(Point pMiddle, float radius, Double lineK) {
        Point[] points = new Point[2];

        float radian, xOffset = 0, yOffset = 0;
        if (lineK != null) {
            radian = (float) Math.atan(lineK);
            xOffset = (float) (Math.sin(radian) * radius);
            yOffset = (float) (Math.cos(radian) * radius);
        } else {
            xOffset = radius;
            yOffset = 0;
        }
        points[0] = new Point((float) NumberUtil.add(pMiddle.getPointX() , xOffset), (float) NumberUtil.sub(pMiddle.getPointY() , yOffset));
        points[1] = new Point((float) NumberUtil.sub(pMiddle.getPointX() , xOffset), (float) NumberUtil.add(pMiddle.getPointY() , yOffset));

        return points;
    }
}
